/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 *
 * Copyright 2010 yura, Version 2.0 (the "License");
 *
 * you may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *
 * Unless required by applicable law or agreed to in writing, software
 *
 * distributed under the License is distributed on an "AS IS" BASIS,
 *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 *
 * limitations under the License.
 */

package org.opu.gui.docviewer;

import java.util.ArrayList;
import java.util.Collection;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument.ElementSpec;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import org.apache.poi.hwpf.usermodel.CharacterRun;
import org.apache.poi.hwpf.usermodel.Paragraph;
import org.apache.poi.hwpf.usermodel.Table;
import org.apache.poi.hwpf.usermodel.TableCell;
import org.apache.poi.hwpf.usermodel.TableRow;
import org.opu.gui.docviewer.table.TableDocument;

/**
 *
 * @author yura
 */
public class GUIBuilder {

    protected TableDocument styleDocument;

    /**
     * Constructs a talbe document.
     * @param document Document with data
     */
    public GUIBuilder() {
        this(new TableDocument());
    }

    /**
     * Constructs a talbe document.
     * @param document Document with data
     */
    public GUIBuilder(TableDocument styleDocument) {
        this.styleDocument = styleDocument;
    }


    public TableDocument getStyleDocument() {
        return styleDocument;
    }

    public void append(Paragraph par) {
        insertString(par.text(), getAttributeSet(par, par.getCharacterRun(0)));
    }

    public void insertString(String str, AttributeSet a){
        try {
            styleDocument.insertString(styleDocument.getLength(), str, a);
        } catch (BadLocationException ex) {
        }
    }

    public int appendTable(Table table) {
        SimpleAttributeSet attrs = new SimpleAttributeSet();
        SimpleAttributeSet tableAttrs = new SimpleAttributeSet();
        ArrayList tableSpecs = new ArrayList();
        
        //close paragraph tag
        tableSpecs.add(new ElementSpec(attrs, ElementSpec.EndTagType));

        //start table tag
        tableAttrs.addAttribute(TableDocument.ElementNameAttribute, TableDocument.ELEMENT_NAME_TABLE);
        ElementSpec tableStart = new ElementSpec(tableAttrs, ElementSpec.StartTagType);
        tableSpecs.add(tableStart);

        //add all rows in table
        tableSpecs.addAll(this.getAllRows(table));
        
        //end table tag
        ElementSpec tableEnd = new ElementSpec(tableAttrs, ElementSpec.EndTagType);
        tableSpecs.add(tableEnd);

        //open new paragraph after table
        tableSpecs.add(new ElementSpec(attrs, ElementSpec.StartTagType));

        //to array
        ElementSpec[] spec = new ElementSpec[tableSpecs.size()];
        tableSpecs.toArray(spec);

        //insert data
        try {
            styleDocument.insert(styleDocument.getLength(), spec);
        } catch (BadLocationException ex) {
        }

        return table.numParagraphs();
    }

    private Collection getAllRows(Table table) {
        ArrayList rows = new ArrayList();

        SimpleAttributeSet rowAttrs = new SimpleAttributeSet();
        rowAttrs.addAttribute(TableDocument.ElementNameAttribute, TableDocument.ELEMENT_NAME_ROW);
        
        int numRows = table.numRows();
        for (int i = 0; i < numRows; i++) {
            ElementSpec rowStart = new ElementSpec(rowAttrs, ElementSpec.StartTagType);
            rows.add(rowStart);

            rows.addAll(this.getAllCells(table.getRow(i)));

            ElementSpec rowEnd = new ElementSpec(rowAttrs, ElementSpec.EndTagType);
            rows.add(rowEnd);
        }

        return rows;
    }

    private Collection getAllCells(TableRow row) {
        ArrayList cells = new ArrayList();
        int numCells = row.numCells();

        for (int i = 0; i< numCells; i++) {
            TableCell cell = row.getCell(i);
            SimpleAttributeSet cellAttrs = new SimpleAttributeSet();
            cellAttrs.addAttribute(TableDocument.ElementNameAttribute, TableDocument.ELEMENT_NAME_CELL);
            cellAttrs.addAttribute(TableDocument.PARAM_CELL_WIDTH, cellWidth(cell.getWidth()));

            ElementSpec cellStart = new ElementSpec(cellAttrs, ElementSpec.StartTagType);
            cells.add(cellStart);
            
            int numParagraphs = cell.numParagraphs();
            for (int j = 0; j < numParagraphs; j ++) {
                cells.addAll(this.getAllTexts(cell.getParagraph(j)));
            }

            ElementSpec cellEnd = new ElementSpec(cellAttrs, ElementSpec.EndTagType);
            cells.add(cellEnd);
        }

        return cells;
    }

    protected Integer cellWidth(int width) {
        if (width > 100){
            return new Integer(width/14);
        } else {
            return new Integer(100);
        }
    }
    
    public Collection getAllTexts(Paragraph text) {
        ArrayList texts = new ArrayList();

        ElementSpec parStart = new ElementSpec(new SimpleAttributeSet(), ElementSpec.StartTagType);
        texts.add(parStart);
        
        int numCharacterRuns = text.numCharacterRuns();
        for (int i = 0; i < numCharacterRuns; i++) {
            CharacterRun tb = text.getCharacterRun(i);
            MutableAttributeSet atr = getAttributeSet(text, tb);
            texts.add(this.textToElement(tb.text(), atr));
        }
        
        ElementSpec parContent = new ElementSpec(new SimpleAttributeSet(),
                ElementSpec.ContentType, "\n".toCharArray(), 0, 1);
        texts.add(parContent);

        ElementSpec parEnd = new ElementSpec(new SimpleAttributeSet(), ElementSpec.EndTagType);
        texts.add(parEnd);
        
        return texts;
    }

    public ElementSpec textToElement(String text, AttributeSet attribute){
        char[] arr = text.toCharArray();
        short elementType = ElementSpec.ContentType;
        return new ElementSpec(attribute, elementType, arr, 0, arr.length);
    }

    public MutableAttributeSet getAttributeSet(Paragraph paragraph, CharacterRun block){
        return new SimpleAttributeSet();
    }

}
